
#include <BStyle>
#include <BPainter>
#include <BRender>
#include <BViewer>
#include <BScene>
#include <BCone>
#include <BCube>
#include <BImage>
#include <BMaterial>
#include <BReadWrite>
#include <BContact>

#include "PushHandler.h"

PushHandler::PushHandler()
{
	_forceSize = 1;

	_cone_x = new BCone();
	_cone_x->setDepthTest(false);
	_cone_x->setRadius(_forceSize * (BReal)0.25);
	_cone_x->setHeight(_forceSize * (BReal)0.5);
	_cone_x->setColor(200, 0, 0);

	_cone_y = new BCone();
	_cone_y->setDepthTest(false);
	_cone_y->setRadius(_forceSize * (BReal)0.25);
	_cone_y->setHeight(_forceSize * (BReal)0.5);
	_cone_y->setColor(0, 200, 0);

	_cone_z = new BCone();
	_cone_z->setDepthTest(false);
	_cone_z->setRadius(_forceSize * (BReal)0.25);
	_cone_z->setHeight(_forceSize * (BReal)0.5);
	_cone_z->setColor(0, 0, 200);

	_lengthText = new BTextual();
	_lengthText->setColor(200, 0, 0);
	_lengthText->setCullback(false);
	_lengthText->setLighting(false);
	_lengthText->setPolyMode(Poly_Fill);
	_lengthText->setGlyphSize((BReal)0.3);

	_node = new BBody("node");
	{
		_node->setMass(1);
		//_node->setForce(BVector(1, 2, 3));
		_node->setContinuous(true);
		_node->setRestitution(0);
		//_node->setGravity(0, 0, -1);

		BCube* cube = new BCube(0.4, 12);
		cube->setColor(100, 200, 255);
		_node->insertShape(cube);

	}

}
PushHandler::~PushHandler()
{

}

void PushHandler::attached(BViewer* viewer)
{
	BScene* dscene = viewer->scene();
	_node->setPosition(0, 0, 5);
	dscene->insert(_node);
	_lengthText->setFont((BFont*)viewer->realFont());
	viewer->scene()->insert(_lengthText);
	this->emit("edit-node", _node);
}
void PushHandler::detached(BViewer* viewer)
{
	BScene* dscene = viewer->scene();
	dscene->remove(_node);
	viewer->scene()->remove(_lengthText);
}

void PushHandler::paint(BPainter& painter)
{
	BViewer* viewer = this->viewer();
}
void PushHandler::render(BRender& render)
{
	render.setLighting(false);
	render.setDepthTest(false);
	render.setLineSmooth(true);
	render.setLineWidth(1);

	BVector force = _node->force();

	const BMatrix& matrix = _node->matrix();
	BVector origin = matrix.position();
	if (force.x() != 0)
	{
		BVector pointX(_forceSize, 0, 0);
		pointX *= matrix;
		_cone_x->setPosition(pointX);
		_cone_x->setRotate(BQuater(BVector(0, 1, 0), PI * 0.5));
		render.setColor(200, 0, 0);
		render.drawLine(origin, pointX);
		render.drawShape(_cone_x);
	}
	if (force.y() != 0)
	{
		BVector pointY(0, _forceSize * force.y(), 0);
		pointY *= matrix;
		_cone_y->setPosition(pointY);
		_cone_y->setRotate(BQuater(BVector(1, 0, 0), -PI * 0.5));
		render.setColor(0, 200, 0);
		render.drawLine(origin, pointY);
		render.drawShape(_cone_y);
	}
	if (force.z() != 0)
	{
		BVector pointZ(0, 0, _forceSize * force.z());
		pointZ *= matrix;
		_cone_z->setPosition(pointZ);
		render.setColor(0, 0, 200);
		render.drawLine(origin, pointZ);
		render.drawShape(_cone_z);
	}

	const BContactArray& contacts = this->scene()->query("contacts");
	for (int i = 0; i < contacts.size(); i++)
	{
		const BContact* contact = contacts[i];
	}
}

void PushHandler::styleEvent(const BEvent& event)
{
	BHandler::styleEvent(event);
	const BStyle* style = event.value();
	BImage* image = style->image("cone-texture");
	if (BShape* shape = _node->shape(0))
	{
		shape->setTexture(image);
	}
}
